package com.haredot.config;

import com.haredot.filter.BearerTokenAuthorizationFilter;
import com.haredot.filter.JWTAuthenticationFilter;
import com.haredot.properties.JwtProperties;
import com.haredot.security.HaredotAccessDeniedHandler;
import com.haredot.security.HaredotAuthenticationFailureHandler;
import com.haredot.security.HaredotAuthenticationSuccessHandler;
import com.haredot.security.JsonAuthenticationEntryPoint;
import com.haredot.service.impl.UserDetailsServiceImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
@EnableWebSecurity
@EnableConfigurationProperties(JwtProperties.class)
public class SecurityConfig {

    @Resource
    private JwtProperties jwtProperties ;

    @Resource
    private StringRedisTemplate stringRedisTemplate ;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.authorizeHttpRequests()
                .antMatchers("/alipay/generator/order/*","/alipay/pay/**" , "" +
                        "/order/**",
                        "/res/add", "/res/upload", "/res/collect/**" , "/res/checkPermission/**" ,
                        "/notify/unReadMessage",
                        "/collect/**" ,
                        "/comment/**" ,
                        "/user/**", "/message/**")
                .authenticated()
                .anyRequest().permitAll();


        http.exceptionHandling()
                .accessDeniedHandler(new HaredotAccessDeniedHandler()) // 处理403 禁止访问错误
                .authenticationEntryPoint(new JsonAuthenticationEntryPoint());
        // 禁用 登录

        http.formLogin()
                .loginProcessingUrl("/api/token")
                .failureHandler(new HaredotAuthenticationFailureHandler())
                .successHandler(new HaredotAuthenticationSuccessHandler(jwtProperties, stringRedisTemplate));

        // 禁用 csrf 保护
        http.csrf().disable();
        // 允许跨域
        http.cors();
        // 设置前后端工作模式
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        http.addFilterBefore(new BearerTokenAuthorizationFilter(jwtProperties), UsernamePasswordAuthenticationFilter.class);
        // 添加过滤器
        http.addFilterBefore(new JWTAuthenticationFilter(userDetailsService(), jwtProperties, stringRedisTemplate), UsernamePasswordAuthenticationFilter.class);


        return http.build();
    }
}
